#include "mytcpsocket.h"
#include <QJsonDocument>
#include <QFileInfo>
#include <QMessageBox>

GlobalObject* GlobalObject::globalObject = new GlobalObject;

GlobalObject::GlobalObject(QObject *parent)
    : QObject{parent}
{
    tcpsocket = new MyTcpSocket;
    connect(tcpsocket,&MyTcpSocket::connected,[=](){
        qDebug()<<"connect to server success";
    });
    connect(tcpsocket,&MyTcpSocket::readyRead,[=](){

        QString buf = tcpsocket->readAll();
        qDebug()<<"buf:  "<<buf;
        QStringList tl = buf.split('$');
        for(int i = 0;i<tl.size();i++){
            qDebug()<<"recv:"<<tl[i];
            emit tcpsocket->jsonRecv(tl[i]);  //将 json 发送的主控程序处理
        }
    });

    currentSelectUid = 0;
    currentSendFileUid = 0;
    currentSendFileGid = 0;
    sendfilePath = "";
    uploadFileID = "";
    upload_file_flag = 0;

    mapJoy = {
        {0,"xiaolian.png"},
        {1,"kuqi.png"},
        {2,"liuhan.png"}
    };

    qDebug()<<"GlobalObject init success";

}

void GlobalObject::deleteFriendFromList(int fuid)
{
    for(auto it = userInfo.friend_list.begin();it!=userInfo.friend_list.end();it++){
        if(it->dd_num == fuid){
            userInfo.friend_list.erase(it);
            return;
        }
    }
}

void GlobalObject::deleteGroupFromList(int gid)
{
    for(auto it = userInfo.group_list.begin();it!=userInfo.group_list.end();it++){
        if(it->gid == gid){
            userInfo.group_list.erase(it);
            return;
        }
    }
}

void GlobalObject::updateFriendStatus(int fuid, int status)
{
    //更新好友链表中的状态
    for(int i = 0;i<userInfo.friend_list.size();i++){
        if(userInfo.friend_list[i].dd_num == fuid){
            userInfo.friend_list[i].status = status;
            break;
        }
    }
}

st_friendData GlobalObject::getFriendInfo(int fuid)
{
    struct st_friendData fdata;
    for(auto it = userInfo.friend_list.begin();it!= userInfo.friend_list.end();it++){
        if(it->dd_num == fuid){
            fdata = *it;
            break;
        }
    }
    return fdata;
}

st_gData GlobalObject::getGroupInfo(int gid)
{
    struct st_gData gdata;
    for(auto it = userInfo.group_list.begin();it!= userInfo.group_list.end();it++){
        if(it->gid == gid){
            gdata = *it;
            break;
        }
    }
    return gdata;
}


void GlobalObject::sendRequest(QVariantMap map)
{
    QString request;
    QJsonDocument doc = QJsonDocument::fromVariant(map);
    request = doc.toJson(QJsonDocument::Compact);  //转换成非格式化的json字符串
    //发送请求
    tcpsocket->write(request.toUtf8());

}

void GlobalObject::sendRequest(QByteArray bytes)
{
    tcpsocket->write(bytes);
}

GlobalObject *GlobalObject::getGlobalObject()
{
    return globalObject;
}

MyTcpSocket *GlobalObject::getTcpsocket() const
{
    return tcpsocket;
}

st_userInfo GlobalObject::getUserInfo() const
{
    return userInfo;
}

int GlobalObject::getCurrentSelectUid() const
{
    return currentSelectUid;
}

void GlobalObject::setCurrentSelectUid(int newCurrentSelectUid)
{
    currentSelectUid = newCurrentSelectUid;
}

int GlobalObject::getCurrentSendFileUid() const
{
    return currentSendFileUid;
}

void GlobalObject::setCurrentSendFileUid(int newCurrentSendFileUid)
{
    currentSendFileUid = newCurrentSendFileUid;
}

QString GlobalObject::getSendfilePath() const
{
    return sendfilePath;
}

void GlobalObject::setSendfilePath(const QString &newSendfilePath)
{
    qDebug()<<"newSendfilePath:"<<newSendfilePath;
    sendfilePath = newSendfilePath;
    qDebug()<<"sendfilePath:"<<sendfilePath;
}

QMap<int, QString> GlobalObject::getMapJoy() const
{
    return mapJoy;
}

QString GlobalObject::getUploadFileID() const
{
    return uploadFileID;
}

void GlobalObject::setUploadFileID(const QString &newUploadFileID)
{
    uploadFileID = newUploadFileID;
}

int GlobalObject::getCurrentSelectGid() const
{
    return currentSelectGid;
}

void GlobalObject::setCurrentSelectGid(int newCurrentSelectGid)
{
    currentSelectGid = newCurrentSelectGid;
}

int GlobalObject::getCurrentSendFileGid() const
{
    return currentSendFileGid;
}

void GlobalObject::setCurrentSendFileGid(int newCurrentSendFileGid)
{
    currentSendFileGid = newCurrentSendFileGid;
}

int GlobalObject::getUpload_file_flag() const
{
    return upload_file_flag;
}

void GlobalObject::setUpload_file_flag(int newUpload_file_flag)
{
    upload_file_flag = newUpload_file_flag;
}

QString GlobalObject::getSaveFileLocalPath() const
{
    return saveFileLocalPath;
}

void GlobalObject::setSaveFileLocalPath(const QString &newSaveFileLocalPath)
{
    saveFileLocalPath = newSaveFileLocalPath;
}

QString GlobalObject::getSaveFileSrvPath() const
{
    return saveFileSrvPath;
}

void GlobalObject::setSaveFileSrvPath(const QString &newSaveFileSrvPath)
{
    saveFileSrvPath = newSaveFileSrvPath;
}


void GlobalObject::setUserInfo(st_userInfo newUserInfo)
{
    userInfo = newUserInfo;
}

void GlobalObject::insertGroupElement(st_gData gdata)
{
    userInfo.group_list.push_back(gdata);
}

void GlobalObject::insertFriendElement(st_friendData fdata)
{
    userInfo.friend_list.push_back(fdata);
}

void GlobalObject::uploadToServer(const QString &localpath, const QString& srvpath)
{
    // 创建QProcess对象
    QProcess *process = new QProcess(this);

    // 设置scp命令和参数
    QString program = "scp"; // scp命令
    QStringList arguments; // 参数列表
    arguments << localpath << srvpath;

    // 连接QProcess的信号到适当的槽
    connect(process, &QProcess::readyReadStandardOutput, this, &GlobalObject::readStandardOutput);
    connect(process, &QProcess::readyReadStandardError, this, &GlobalObject::readStandardError);
    connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &GlobalObject::uploadProcessFinished);

    // 开始执行scp命令
    process->start(program, arguments);

    // 如果需要，你可以在这里处理进程的输出和错误
}

void GlobalObject::downloadToLocal(const QString &srvpath, const QString& localpath)
{
    // 创建QProcess对象
    QProcess *process = new QProcess(this);

    // 设置scp命令和参数  用户名@Linux主机地址:远程文件路径 本地文件路径
    QString program = "scp"; // scp命令
    QStringList arguments; // 参数列表
    arguments << srvpath << localpath;

    // 连接QProcess的信号到适当的槽
    connect(process, &QProcess::readyReadStandardOutput, this, &GlobalObject::readStandardOutput);
    connect(process, &QProcess::readyReadStandardError, this, &GlobalObject::readStandardError);
    connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &GlobalObject::downloadProcessFinished);

    // 开始执行scp命令
    process->start(program, arguments);

}

void GlobalObject::uploadToServer_Small(const QString &localpath, const QString &srvpath)
{
    // 创建QProcess对象
    QProcess *process = new QProcess(this);

    // 设置scp命令和参数
    QString program = "scp"; // scp命令
    QStringList arguments; // 参数列表
    arguments << localpath << srvpath;

    // 连接QProcess的信号到适当的槽
    connect(process, &QProcess::readyReadStandardOutput, this, &GlobalObject::readStandardOutput);
    connect(process, &QProcess::readyReadStandardError, this, &GlobalObject::readStandardError);
    connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &GlobalObject::uploadProcessFinished_Small);

    // 开始执行scp命令
    process->start(program, arguments);
}

void GlobalObject::readStandardOutput()
{
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (process) {
        QString output = process->readAllStandardOutput();
        qDebug() << "Standard Output:" << output;
    }
}

void GlobalObject::readStandardError()
{
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (process) {
        QString error = process->readAllStandardError();
        qDebug()<<"StandarError "<<error;
    }
}

void GlobalObject::uploadProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << "Process finished with exit code" << exitCode << "and exit status" << exitStatus;

    // 检查进程是否成功完成 0-正常 1-崩溃
    if (exitStatus == QProcess::NormalExit && exitCode == 0) {
        // scp传输文件完成后，给服务器发送文件上传完毕
        QVariantMap map;
        map["cmd"] = "upload_finish";
        map["fileID"] = GlobalObject::getGlobalObject()->getUploadFileID();
        QFileInfo fileinfo(GlobalObject::getGlobalObject()->getSendfilePath());
        int partitionID = GlobalObject::getGlobalObject()->getUploadFileID().right(3).toInt() % 7;  // 一共0~9的分区，对7取模
        QString srvpath = QString("/DragonIM/file/%1/%2").arg(partitionID).arg(fileinfo.fileName());
        map["srvpath"] = srvpath;
        map["filesize"] = fileinfo.size();

        //发送文件上传完毕
        GlobalObject::getGlobalObject()->sendRequest(map);
    } else {
         QMessageBox::warning(nullptr,"上传失败","文件传输过程产生错误!",QMessageBox::Ok);
    }

    // 清理QProcess对象（如果它是在堆上创建的）
    // 注意：如果你在栈上创建了QProcess对象，就不需要删除它
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (process) {
        process->deleteLater();
    }
}

void GlobalObject::uploadProcessFinished_Small(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << "Process finished with exit code" << exitCode << "and exit status" << exitStatus;

    // 检查进程是否成功完成 0-正常 1-崩溃
    if (exitStatus == QProcess::NormalExit && exitCode == 0) {
        qDebug()<<"upload file successful";
    } else {
         QMessageBox::warning(nullptr,"上传失败","文件传输过程产生错误!",QMessageBox::Ok);
    }

    // 清理QProcess对象（如果它是在堆上创建的）
    // 注意：如果你在栈上创建了QProcess对象，就不需要删除它
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (process) {
        process->deleteLater();
    }
}

void GlobalObject::downloadProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{

    // 检查进程是否成功完成
    if (exitStatus == QProcess::NormalExit && exitCode == 0) {
        qDebug() << "download successfully.";
    } else {
        qDebug() << "There was an error transferring the file.";
    }

    // 清理QProcess对象（如果它是在堆上创建的）
    // 注意：如果你在栈上创建了QProcess对象，就不需要删除它
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (process) {
        process->deleteLater();
    }
}

